#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define MAX_CLIENTS 10
#define BUFFER_SIZE 1024

int main() {
    int server_fd, client_fds[MAX_CLIENTS], max_fd, activity, i, sd;
    int max_clients = MAX_CLIENTS;
    fd_set read_fds, master_fds;
   
    struct sockaddr_in address;
    
    char buffer[BUFFER_SIZE];
    
    // 1. 创建服务器socket
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd < 0) {
        perror("Socket creation failed");
        return 1;
    }
    
    int optval = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEPORT, &optval, 4);

    // 2. 绑定地址
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(8080);
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("Bind failed");
        return 1;
    }
    
    // 3. 监听连接
    if (listen(server_fd, 5) < 0) {
        perror("Listen failed");
        return 1;
    }
    
    // 4. 初始化client_fds数组
    for (i = 0; i < max_clients; i++) {
        client_fds[i] = -1;
    }
    
    // 5. 将server_fd添加到master_fds
    FD_ZERO(&master_fds);
    FD_SET(server_fd, &master_fds);
    max_fd = server_fd;
    
    printf("Server started on port 8080...\n");
    
    // 6. 主循环：使用select监听事件
    while (1) {
        // 复制master_fds到read_fds
        read_fds = master_fds;
        
        // 等待IO事件，超时时间设为NULL（阻塞等待）
        activity = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
        if (activity < 0) {
            perror("Select error");
            break;
        }
        
        // 7. 检查server_fd是否有新连接
        if (FD_ISSET(server_fd, &read_fds)) {
            // 接受新连接
            struct sockaddr_in client_addr;
            socklen_t client_len = sizeof(client_addr);
            sd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len);
            if (sd < 0) {
                perror("Accept failed");
                continue;
            }
            
            // 打印客户端信息并添加到client_fds
            char client_ip[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, sizeof(client_ip));
            printf("New client connected: %s:%d\n", client_ip, ntohs(client_addr.sin_port));
            
            // 查找空闲位置存储client_fd
            for (i = 0; i < max_clients; i++) {
                if (client_fds[i] < 0) {
                    client_fds[i] = sd;
                    break;
                }
            }
            
            // 将新client_fd添加到master_fds
            FD_SET(sd, &master_fds);
            if (sd > max_fd) {
                max_fd = sd;
            }
        }
        
        // 8. 检查所有client_fd是否有数据可读
        for (i = 0; i < max_clients; i++) {
            sd = client_fds[i];
            if (sd > 0 && FD_ISSET(sd, &read_fds)) {
                // 读取客户端数据
                int bytes_read = read(sd, buffer, BUFFER_SIZE);
                if (bytes_read > 0) {
                   // 处理数据（示例：回显给客户端）
                    buffer[bytes_read] = '\0';
                    printf("Received: %s\n", buffer);
                    write(sd, buffer, bytes_read);
                } else {
                    perror("Client disconnected or Read error!\n");
                    close(sd);
                    FD_CLR(sd, &master_fds);
                    client_fds[i] = -1;
                }
            }
        }
    }
    
    // 清理资源
    for (i = 0; i < max_clients; i++) {
        if (client_fds[i] > 0) {
            close(client_fds[i]);
        }
    }
    close(server_fd);
    return 0;
}